package com.example.springbootexamples;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class Tps {


    static Logger logger= LoggerFactory.getLogger(Tps.class);
    static AtomicInteger request=new AtomicInteger();
    static AtomicInteger total=new AtomicInteger();
    static AtomicInteger success=new AtomicInteger();
    static AtomicInteger fail=new AtomicInteger();
    static volatile long e;
    static volatile long now;
    public static void main(String[] args) {
        //SpringApplication.run(DemoApplication.class, args);
        Integer t=1;
        Integer min=10;
        Integer million=1;
        if(args.length==3) {
            t = Integer.parseInt(args[0]);
             min = Integer.parseInt(args[1]);
             million = Integer.parseInt(args[2]);
        }
        int nn=million*100*10000;
        final long l=System.currentTimeMillis();
        //e=l+min*60*1000l;
        e=l+min*1000l;
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    Date d = new Date();
                    now = d.getTime();
                    logger.info("now {} start {}" , d,new Date(l));
                    if(now>=e) break;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException interruptedException) {
                        interruptedException.printStackTrace();
                    }
                }
            }
        }).start();
        BlockingDeque blockingDeque=new LinkedBlockingDeque();
        ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(t,t,10000, TimeUnit.HOURS,blockingDeque);
        int n=0;
        List<Double> doubleList=new ArrayList<>();
        Map<String,List<Long>> map=new HashMap<>();
        while(true){
            if(n<nn) {
                n=request.incrementAndGet();
                threadPoolExecutor.submit(new Run(threadPoolExecutor, total, success, fail,map));
            }else {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
            }
            if(now>=e) break;
        }
        double tps=success.get()/Double.valueOf(min);
        int size=blockingDeque.size();
        long ll=0;
        for(String k:map.keySet()){
            List<Long> list=map.get(k);
            for(Long d:list){
                ll+=d;
            }
        }
        double durationavg=ll/Double.valueOf(success.get());
        logger.info("===second {} thread {} total {} success {} fail {} tps {} durationavg {}",min,t,total.get(),success.get(),fail.get(),tps,durationavg);
        logger.info("===start {} end {} request {} queue size {}",new Date(l),new Date(e),request.get(),size);
        threadPoolExecutor.shutdownNow();

    }

}
